package com.algo.sns;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

import java.util.regex.*;

import java.io.File;  
import java.io.*; 

public class DaDecoder {
	/* "A-Z a-z 0-9 +(-) /(_)" maps to 0-63 */
	static final byte []table = {
	/*	 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 - 0x0F */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 - 0x1F */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, /* 0x20 - 0x2F */
		52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 - 0x3F */
		-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 0x40 - 0x4F */
		15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, /* 0x50 - 0x5F */
		-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 - 0x6F */
		41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70 - 0x7F */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 - 0x8F */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 - 0x9F */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 - 0xAF */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 - 0xBF */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 - 0xCF */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 - 0xDF */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 - 0xEF */
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xF0 - 0xFF */
	};
	
	public static String decode(String str, boolean onlySns)
	{
		if (str == null || str.length() < 10)
			return null;
		String[] strs = str.split(",");
		StringBuilder sb = new StringBuilder();
		int pos = 0;
		if(onlySns)	pos = 8;
		for (int i = 0; i < strs.length; i++){
			String sns = decodeOne(strs[i].substring(pos), onlySns);
			if(sns != null)
				sb.append(sns + ",");
		}
		if(sb.length() > 1) sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}
	
	
	private static String decodeOne(String str, boolean onlySns)
	{
		if (str == null || str.length() < 3)
			return null;
		byte result[] = new byte[100];
		int j = 0;
		for (int i = 0, group = 0; i < str.length(); i++)
		{
			byte ch = (byte)table[str.charAt(i)&0xff];
			if (ch < 0) 
				return null; /* invalid characters */
			switch(group) 
			{
				case 0:			
					result[j] = (byte)(ch << 2);
					group = 1;
					break;
				case 1:
					result[j++] |= (byte)((ch & 0xff) >>> 4);
					result[j] = (byte)((ch & 0x0f) << 4);
					group = 2;
					break;
				case 2:
					result[j++] |= (byte)((ch & 0xff) >>> 2);
					result[j] = (byte)((ch & 0x03) << 6);
					group = 3;
					break;
				case 3:
					result[j++] |= (byte)ch;
					group = 0;
					break;
			}
		}
		if(onlySns)
			for (int i = 1; i < j; i++)
                        	result[i] = (byte)(result[i]&0x7f);
		else	for (int i = 1; i < j; i++)
				result[i] = (byte)(result[i]&0x7f);
		return new String(result, 0, j);
	}
}
